package partlow.yelp;

import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.scribe.builder.ServiceBuilder;
import org.scribe.builder.api.DefaultApi10a;
import org.scribe.model.OAuthRequest;
import org.scribe.model.Response;
import org.scribe.model.Token;
import org.scribe.model.Verb;
import org.scribe.oauth.OAuthService;

import parsing.exception.BetterJSONException;
import partlow.yelp.datatypes.Business;
import partlow.yelp.parsers.BusinessParser;

/**
 *
 * @author Devin
 */
public class YelpApiV2 extends DefaultApi10a {
    private static final String DOMAIN = "http://api.yelp.com/v2";
    private static final String SEARCH_ENDPOINT = "/search";
    private static final String CONSUMER_KEY = "ORMKG1GJtPPtsQDdVAHJiw";
    private static final String CONSUMER_SECRET = "wWDPVwIT0LyXAkjGVi8j9n2NshQ";
    private static final String TOKEN = "hYG7fOD2rgZn0V_HF_7fDJaVSUtz9DQi";
    private static final String TOKEN_SECRET = "4Sjg6jGgF3qJqgOdij6bs8qDwDY";
    
    private static OAuthService service;
    private static Token accessToken;
    
    static {
    	service = new ServiceBuilder().provider(YelpApiV2.class).apiKey(CONSUMER_KEY).apiSecret(CONSUMER_SECRET).build();
        accessToken = new Token(TOKEN, TOKEN_SECRET);
    }
    
    public List<Business> getBusinesses(Map<String, String> query) throws MalformedURLException, IOException, YelpException, JSONException{
        List<Business> businesses = new ArrayList<Business>();
        StringBuilder requestStringBuilder = new StringBuilder(DOMAIN).append(SEARCH_ENDPOINT);
        int offsetAmount = 20;
        query.put("limit", ""+offsetAmount);
        query.put("deals_filter", "true");
        
        OAuthRequest request = new OAuthRequest(Verb.GET, requestStringBuilder.toString());
        for(Map.Entry<String, String> entry : query.entrySet()) {
        	String parameterName = entry.getKey();
        	String parameter = entry.getValue();
        	
        	request.addQuerystringParameter(parameterName, parameter);
        }
        
        int offset = 0;
        while(request != null) {
	        service.signRequest(accessToken, request);
	        Response response = request.send();
	        JSONObject jsonObject = buildJSONFromConnection(response);
	        request = null;
	        
	        // check for error
        	if(jsonObject.has("error"))
        		break;
        	
        	//  get businesses
        	JSONArray businessArray = jsonObject.getJSONArray("businesses");
	        businesses.addAll(new BusinessParser().parse(businessArray));
        	
	        // get count
	        if(!jsonObject.has("total"))
	        	break;
        	int total = jsonObject.getInt("total");
        	offset += offsetAmount;
        	if(offset >= total)
        		break;
	        	
	        // build new request with offset
        	query.put("offset", ""+offset);
        	request = new OAuthRequest(Verb.GET, requestStringBuilder.toString());
            for(Map.Entry<String, String> entry : query.entrySet()) {
            	String parameterName = entry.getKey();
            	String parameter = entry.getValue();
            	
            	request.addQuerystringParameter(parameterName, parameter);
            }
        }
        
        return businesses;
    }
    
    private JSONObject buildJSONFromConnection(Response response) throws IOException, BetterJSONException{
        String jsonString = response.getBody();
        JSONObject json;
		try {
			json = new JSONObject(jsonString);
		} catch (JSONException e) {
			throw new BetterJSONException(e.getMessage(), jsonString);
		}
        return json;
    }

	@Override
	public String getAccessTokenEndpoint() {
		return null;
	}

	@Override
	public String getAuthorizationUrl(Token arg0) {
		return null;
	}

	@Override
	public String getRequestTokenEndpoint() {
		return null;
	}

}
